package com.carol.lmsbe.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carol.lmsbe.dto.*;
import com.carol.lmsbe.entity.Equipment;
import com.carol.lmsbe.entity.EquipmentScrap;
import com.carol.lmsbe.entity.User;
import com.carol.lmsbe.mapper.EquipmentScrapMapper;
import com.carol.lmsbe.mapper.EquipmentMapper;
import com.carol.lmsbe.mapper.UserMapper;
import com.carol.lmsbe.service.EquipmentScrapService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设备报废服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class EquipmentScrapServiceImpl implements EquipmentScrapService {

    private final EquipmentScrapMapper equipmentScrapMapper;
    private final EquipmentMapper equipmentMapper;
    private final UserMapper userMapper;

    @Override
    public Page<EquipmentScrapDTO> listScrapRecords(EquipmentScrapQueryRequest request) {
        Page<EquipmentScrap> page = new Page<>(request.getPageNum(), request.getPageSize());
        
        LambdaQueryWrapper<EquipmentScrap> queryWrapper = new LambdaQueryWrapper<>();
        
        if (request.getEquipmentId() != null) {
            queryWrapper.eq(EquipmentScrap::getEquipmentId, request.getEquipmentId());
        }
        if (request.getHandlerId() != null) {
            queryWrapper.eq(EquipmentScrap::getResponsiblePerson, request.getHandlerId().toString());
        }
        if (request.getScrapDateStart() != null) {
            queryWrapper.ge(EquipmentScrap::getScrapDate, request.getScrapDateStart());
        }
        if (request.getScrapDateEnd() != null) {
            queryWrapper.le(EquipmentScrap::getScrapDate, request.getScrapDateEnd());
        }
        if (StringUtils.hasText(request.getReason())) {
            queryWrapper.like(EquipmentScrap::getScrapReason, request.getReason());
        }
        
        queryWrapper.orderByDesc(EquipmentScrap::getCreateTime);
        
        Page<EquipmentScrap> scrapPage = equipmentScrapMapper.selectPage(page, queryWrapper);
        
        // 转换为DTO
        Page<EquipmentScrapDTO> result = new Page<>();
        BeanUtils.copyProperties(scrapPage, result, "records");
        
        List<EquipmentScrapDTO> records = scrapPage.getRecords().stream().map(scrap -> {
            EquipmentScrapDTO dto = new EquipmentScrapDTO();
            BeanUtils.copyProperties(scrap, dto);
            
            // 设置设备名称、编号和原价值
            if (scrap.getEquipmentId() != null) {
                Equipment equipment = equipmentMapper.selectById(scrap.getEquipmentId());
                if (equipment != null) {
                    dto.setEquipmentName(equipment.getName());
                    dto.setEquipmentCode(equipment.getCode());
                    dto.setOriginalValue(equipment.getUnitPrice());
                }
            }
            
            // 手动设置字段
            dto.setScrapReason(scrap.getScrapReason());
            dto.setScrapMethod(scrap.getScrapMethod());
            dto.setDisposalValue(scrap.getDisposalValue());
            dto.setResponsiblePerson(scrap.getResponsiblePerson());
            dto.setApprovalPerson(scrap.getApprovalPerson());
            
            return dto;
        }).collect(Collectors.toList());
        
        result.setRecords(records);
        return result;
    }

    @Override
    public EquipmentScrapDTO getScrapRecordById(Long id) {
        EquipmentScrap scrap = equipmentScrapMapper.selectById(id);
        if (scrap == null) {
            throw new RuntimeException("报废记录不存在");
        }
        
        EquipmentScrapDTO dto = new EquipmentScrapDTO();
        BeanUtils.copyProperties(scrap, dto);
        
        // 设置设备名称、编号和原价值
        if (scrap.getEquipmentId() != null) {
            Equipment equipment = equipmentMapper.selectById(scrap.getEquipmentId());
            if (equipment != null) {
                dto.setEquipmentName(equipment.getName());
                dto.setEquipmentCode(equipment.getCode());
                dto.setOriginalValue(equipment.getUnitPrice());
            }
        }
        
        // 手动设置字段
        dto.setScrapReason(scrap.getScrapReason());
        dto.setScrapMethod(scrap.getScrapMethod());
        dto.setDisposalValue(scrap.getDisposalValue());
        dto.setResponsiblePerson(scrap.getResponsiblePerson());
        dto.setApprovalPerson(scrap.getApprovalPerson());
        
        return dto;
    }

    @Override
    @Transactional
    public EquipmentScrapDTO createScrapRecord(EquipmentScrapRequest request) {
        // 检查设备是否存在
        Equipment equipment = equipmentMapper.selectById(request.getEquipmentId());
        if (equipment == null) {
            throw new RuntimeException("设备不存在");
        }
        
        EquipmentScrap scrap = new EquipmentScrap();
        BeanUtils.copyProperties(request, scrap);
        
        equipmentScrapMapper.insert(scrap);
        
        // 更新设备状态为已报废
        equipment.setStatus("SCRAPPED");
        equipmentMapper.updateById(equipment);
        
        return getScrapRecordById(scrap.getId());
    }

    @Override
    @Transactional
    public EquipmentScrapDTO updateScrapRecord(EquipmentScrapUpdateRequest request) {
        EquipmentScrap scrap = equipmentScrapMapper.selectById(request.getId());
        if (scrap == null) {
            throw new RuntimeException("报废记录不存在");
        }
        
        BeanUtils.copyProperties(request, scrap);
        equipmentScrapMapper.updateById(scrap);
        
        return getScrapRecordById(scrap.getId());
    }

    @Override
    @Transactional
    public void deleteScrapRecord(Long id) {
        EquipmentScrap scrap = equipmentScrapMapper.selectById(id);
        if (scrap == null) {
            throw new RuntimeException("报废记录不存在");
        }
        
        equipmentScrapMapper.deleteById(id);
    }

    @Override
    public List<Map<String, Object>> getScrapStatistics(EquipmentStatisticsRequest request) {
        // 这里可以实现具体的统计逻辑
        // 由于涉及复杂的统计查询，暂时返回空数据
        // 实际实现中可以使用自定义SQL查询
        return List.of();
    }

    @Override
    public Page<EquipmentScrapDTO> getMyScrapRecords(EquipmentScrapQueryRequest request) {
        // 获取当前用户ID
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Long currentUserId = getCurrentUserId(authentication);
        
        // 由于数据库中使用的是字符串存储责任人，这里需要特殊处理
        // 暂时返回所有记录，实际应用中需要根据用户ID查询对应的报废记录
        return listScrapRecords(request);
    }

    @Override
    @Transactional
    public void batchDeleteScrapRecords(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        
        equipmentScrapMapper.deleteBatchIds(ids);
    }

    @Override
    public byte[] exportScrapData(EquipmentScrapQueryRequest request) {
        // 这里可以实现Excel导出逻辑
        // 暂时返回空数组
        return new byte[0];
    }

    /**
     * 获取当前用户ID
     */
    private Long getCurrentUserId(Authentication authentication) {
        if (authentication == null || authentication.getPrincipal() == null) {
            throw new RuntimeException("用户未登录");
        }
        
        Object principal = authentication.getPrincipal();
        if (principal instanceof com.carol.lmsbe.security.JwtAuthenticationFilter.UserPrincipal) {
            return ((com.carol.lmsbe.security.JwtAuthenticationFilter.UserPrincipal) principal).getUserId();
        } else if (principal instanceof String) {
            // 如果principal是用户名，则通过用户名查找用户ID
            User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                    .eq(User::getUsername, principal));
            if (user != null) {
                return user.getId();
            }
        }
        
        throw new RuntimeException("无法获取当前用户信息");
    }
}
